#pragma once

#include "SPD3D11Prerequisite.h"
#include <list>

namespace SP
{
	class SPCamera;

	//-------------------------------------------------------------------------
	class DLL_EXPORT SPD3DObject
	{
	public:
		SPD3DObject();
		virtual ~SPD3DObject();

	protected:
		ID3D11Device* m_pDevice;
		ID3D11DeviceContext* m_pImmediateContext;
	};

	//-------------------------------------------------------------------------------------
	class DLL_EXPORT SPD3D11RenderEnvironment
	{
	public:
		DLL_EXPORT friend SPCamera*									SPGetCamera();
		DLL_EXPORT friend ID3D11Device*							SPGetD3D11Device();
		DLL_EXPORT friend ID3D11DeviceContext*				SPGetD3D11DeviceContext();
		DLL_EXPORT friend SPD3D11RenderEnvironment*		SPGetRenderEnvironment();

		HRESULT												Create( HWND hWnd, UINT width, UINT height );
		HRESULT												SetWindow( UINT width, UINT height );
		void														SetCamera( SPCamera* pCamera ){ m_pCamera = pCamera; }

		void														Clear( XMFLOAT4 vColor );
		void														Present();

		HRESULT CompileShaderFromFile( WCHAR* szFileName, 
																D3D_SHADER_MACRO* pDefines, 
																LPCSTR szEntryPoint, 
																LPCSTR szShaderModel, 
																ID3DBlob** ppBlobOut );

		HRESULT CompileShaderFromMemory( LPCSTR pSrcData, 
																SIZE_T SrcDataLen, 
																D3D_SHADER_MACRO* pDefines, 
																LPCSTR szEntryPoint, 
																LPCSTR szShaderModel, 															
																ID3DBlob** ppBlobOut );

		HRESULT CreateBuffer( UINT uElementSize, UINT uCount, VOID* pInitData, ID3D11Buffer** ppBufOut );
		HRESULT CreateBufferSRV( ID3D11Buffer* pBuffer, ID3D11ShaderResourceView** ppSRVOut );
		HRESULT CreateBufferUAV( ID3D11Buffer* pBuffer, ID3D11UnorderedAccessView** ppUAVOut );
		HRESULT CreateSRVFromFile( const WCHAR* strFile, ID3D11ShaderResourceView** ppSRVout );
	
	private:
		static SPD3D11RenderEnvironment* GetD3D11RE();
		SPD3D11RenderEnvironment();
		~SPD3D11RenderEnvironment();

		HRESULT								CreateViews( UINT width, UINT height );

		HWND									m_hWnd;
		D3D_DRIVER_TYPE				m_driverType;
		D3D_FEATURE_LEVEL			m_featureLevel;
		ID3D11Device*						m_pd3dDevice;
		ID3D11DeviceContext*			m_pImmediateContext;
		IDXGISwapChain*					m_pSwapChain;
		ID3D11RenderTargetView*	m_pRenderTargetView;
		ID3D11Texture2D*				m_pDepthStencil;
		ID3D11DepthStencilView*		m_pDepthStencilView;

		UINT										m_nWidth;
		UINT										m_nHeight;

		SPCamera*							m_pCamera;
	};

	DLL_EXPORT SPCamera*								SPGetCamera();
	DLL_EXPORT ID3D11Device*							SPGetD3D11Device();
	DLL_EXPORT ID3D11DeviceContext*				SPGetD3D11DeviceContext();
	DLL_EXPORT SPD3D11RenderEnvironment*	SPGetRenderEnvironment();
}
